using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Domain.Services;
using Domain.Entities;
using System.Collections.Generic;
using Domain.Permissions;

namespace UserInterface
{
    public partial class Search : BoardPageBase
    {
        const string TARGET_ITEM_CATEGORY_ID_PREFIX = "c_";
        const string TARGET_ITEM_FORUM_ID_PREFIX = "f_";
        const string TARGET_ITEM_FORUM_NAME_PREFIX = " - ";

        protected void Page_Load(object sender, EventArgs e)
        {
            string pageTitle = (string)GetLocalResourceObject("Title");

            MasterPage.TitleGenerator.PageTitle = pageTitle;
            MasterPage.HeaderText = pageTitle;
            MasterPage.AddPathItem(pageTitle, "Search.aspx");
            
            if (!IsPostBack)
            {
                IList<Category> categories = CategoryService.GetAll();
                foreach (Category category in categories)
                {
                    List<ListItem> forumListItems = new List<ListItem>();
                    IList<Forum> forums = category.Forums;

                    /*
                     * foreach gave an InvalidOperationException due
                     * to a NHibernate query in method
                     * UserForumPermissionSerivce.GetByUserIdAndForumId.
                     * Reason unknown, so I'm using a for loop until this,
                     * what seems to be a NHibernate bug, is fixed.
                     */
                    for (int i = 0; i < forums.Count; i++)
                    {
                        Forum forum = forums[i];
                        ForumPermissionManager forumPermissionManager = PermissionManager.CreateForumPermissionManager(forum);
                        if (forumPermissionManager.Read)
                        {
                            forumListItems.Add(
                                new ListItem(
                                    TARGET_ITEM_FORUM_NAME_PREFIX + forum.Name,
                                    TARGET_ITEM_FORUM_ID_PREFIX + forum.Id
                                )
                            );
                        }
                    }
                    if (forumListItems.Count > 0)
                    {
                        TargetListBox.Items.Add(
                            new ListItem(
                                category.Name,
                                TARGET_ITEM_CATEGORY_ID_PREFIX + category.Id
                            )
                        );
                        foreach (ListItem forumListItem in forumListItems)
                        {
                            TargetListBox.Items.Add(forumListItem);
                        }
                    }
                }

                string searchTerms = (string)Request.QueryString["terms"];
                if (searchTerms != null)
                {
                    SearchByTerms(searchTerms);
                }
            }
        }

        private void SearchByTerms(string terms)
        {
            PerformSearch(terms);

            KeyWordsTextBox.Text = terms;
        }

        private void PerformSearch(string terms)
        {
            PerformSearch(terms, false, new List<int>(), new List<int>());
        }

        private void PerformSearch(
            string terms,
            bool requireAllTerms,
            List<int> categoryIds,
            List<int> forumIds
        )
        {
            IList<Topic> foundTopics = SearchService.SearchForTopicsByTerms(
                terms,
                requireAllTerms,
                categoryIds,
                forumIds
            );
            foundTopics = PermissionManager.FilterReadableTopics(foundTopics);

            SearchResultsPanel.Visible = true;
            NumberOfTopicsLabel.Text = foundTopics.Count.ToString();

            SearchResultsRepeater.DataSource = foundTopics;
            SearchResultsRepeater.DataBind();
        }

        protected void SearchButton_Click(object sender, EventArgs e)
        {
            string terms = KeyWordsTextBox.Text;
            
            List<int> categoryIds = new List<int>();
            List<int> forumIds = new List<int>();

            foreach (ListItem item in TargetListBox.Items)
            {
                if (item.Selected)
                {
                    if (item.Value.StartsWith(TARGET_ITEM_CATEGORY_ID_PREFIX))
                    {
                        string categoryIdString = item.Value.Substring(
                            TARGET_ITEM_CATEGORY_ID_PREFIX.Length    
                        );
                        int categoryId = int.Parse(categoryIdString);
                        categoryIds.Add(categoryId);
                    }
                    else
                    {
                        string forumIdString = item.Value.Substring(
                            TARGET_ITEM_FORUM_ID_PREFIX.Length
                        );
                        int forumId = int.Parse(forumIdString);
                        forumIds.Add(forumId);
                    }
                }
            }
            
            bool requireAllTerms = TypeRadioButtonList.SelectedIndex == 1;

            PerformSearch(
                terms,
                requireAllTerms,
                categoryIds,
                forumIds
            );
        }
    }
}
